# -*- coding: utf-8 -*-
# @Time    : 2020/10/26 15:27
# @Author  : liuwenfan
# @File    : node_service.py
# @Software: PyCharm

import socket
import time

from application import db
from application.libs import const, result
from application.models.models import Node


def del_node(id):
    """
    删除节点
    :param id:
    :return:
    """
    node = db.session.query(Node).filter(Node.id == id).first()
    try:
        db.session.delete(node)
        db.session.commit()
    except:
        db.session.rollback()
        return const.DELETE_FAIL


# def add_node(node_name, ipv4, content, tasks=3):
def add_node(data):
    """
    添加节点
    :param data:
    :return:
    """
    add_node = Node()
    add_node.node_name = data["node_name"]
    add_node.ipv4 = data["ipv4"]
    add_node.ipv4_port = data["ipv4_port"]
    add_node.callback_ipv4_port = data["callback_ipv4_port"]
    add_node.callback_ip4 = data["callback_ip4"]
    add_node.system = data["system"]
    add_node.content = data["content"]
    try:
        db.session.add(add_node)
        db.session.commit()
        # db.session.close()
        return const.INSERT_SUCCESS
    except:
        db.session.rollback()
        return const.INSERT_FAIL


def update_node(data):
    """
    更新节点
    :param data:
    :return:
    """
    id = data["id"]
    node_name = data["node_name"]
    ipv4 = data["ipv4"]
    callback_ip4 = data["callback_ip4"]
    system = data["system"]
    content = data["content"]
    ipv4_port = data["ipv4_port"]
    callback_ipv4_port = data["callback_ipv4_port"]
    u_time = time.strftime(
        "%Y-%m-%d %H:%M:%S",
        time.localtime())
    db.session.query(Node).filter(Node.id == id).update({"node_name": node_name,
                                                         "ipv4": ipv4,
                                                         "callback_ip4": callback_ip4,
                                                         "system": system,
                                                         "content": content,
                                                         "update_time": u_time, "ipv4_port": ipv4_port,
                                                         "callback_ipv4_port": callback_ipv4_port})
    try:
        db.session.commit()
        # db.session.close()
        return const.EDIT_SUCCESS
    except:
        db.session.rollback()
        return const.EDIT_FAIL


def find_one_node(id):
    node = db.session.query(Node).filter(Node.id == id).first()
    if node:
        ret = {"id": node.id, "node_name": node.node_name, "ipv4": node.ipv4, "content": node.content,
               "tasks": node.tasks}
    else:
        ret = None
    return ret


def node_list(data):
    """
    获取节点列表
    :param data:
    :return:
    """
    nodes = db.session.query(Node).paginate(page=data['page_num'],
                                            per_page=data['page_per'], error_out=False)
    n_list = []
    ret = {}
    if nodes.items:
        for item in nodes.items:
            ret['id'] = item.id
            ret['node_name'] = item.node_name
            ret['ipv4'] = item.ipv4
            ret['content'] = item.content
            ret['tasks'] = item.tasks
            ret['system'] = item.system
            ret['callback_ip4'] = item.callback_ip4
            # ret['status'] = item.status
            ret['create_time'] = item.create_time
            ret['update_time'] = item.update_time
            ret['callback_ipv4_port'] = item.callback_ipv4_port
            ret['ipv4_port'] = item.ipv4_port
            # ret['status'] = _telnet_status(item.ipv4, item.ipv4_port)  # 提供给前端显示，并不是数据库字段
            ret['status'] = "-" # 由于部署在外网，不再查询列表的时候去测试连接
            n_list.append(ret.copy())
            ret.clear()
    ret['items'] = n_list
    ret['total'] = nodes.total
    return ret


def get_node():
    """
    获取节点名称下拉框
    :return:
    """
    nodes = db.session.query(Node.id, Node.node_name).all()
    ret = {}
    if nodes:
        ret = [{"node_id": i, "node_name": j} for i, j in nodes]
    return ret


def obtain_status(id):
    """
    Telnet
    :param id:
    :return:
    """
    node = db.session.query(Node).filter(Node.id == id).first()
    status_dic = {"status": "offline"}
    code = const.FAIL_40000
    if node:
        sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sk.settimeout(1)
        try:
            sk.connect((node.ipv4, int(node.ipv4_port)))
            # sk.connect((node.ipv4, 9527))
            status_dic["status"] = "online"
            code = const.SUCCESS
        except:
            status_dic["status"] = "offline"
            code = const.FAIL_40000
        finally:
            sk.close()
    return result(code, status_dic["status"], status_dic)


def _telnet_status(ipv4, ipv4_port):
    """
    仅在内部调用，测试Telnet
    :param ipv4:
    :param ipv4_port:
    :return:
    """
    sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sk.settimeout(1)
    try:
        sk.connect((ipv4, int(ipv4_port)))
        # sk.connect((node.ipv4, 9527))
        status = "online"
    except:
        status = "offline"
    finally:
        sk.close()
    return status
